<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <title>作者博客：百度"three.js 郭隆邦"</title>
  <style>
    body{
            margin: 0;
            overflow: hidden;//隐藏body窗口区域滚动条
        }
    </style>
  <!--引入three.js三维引擎-->
  <script src="http://www.yanhuangxueyuan.com/versions/threejsR92/build/three.js"></script>
  <!-- 引入threejs扩展控件OrbitControls.js-->
  <script src="http://www.yanhuangxueyuan.com/versions/threejsR92/examples/js/controls/OrbitControls.js"></script>

  <!-- 引入EffectComposer.js库  封装了WebGLRenderTarget  可以调用WebGL渲染器的渲染方法 -->
  <script src="http://www.yanhuangxueyuan.com/threejs/examples/js/postprocessing/EffectComposer.js"></script>

  <!-- renderPass.js库  构造函数传入场景Scene和相机Camera作为构造函数renderPass的参数 -->
  <script src="http://www.yanhuangxueyuan.com/threejs/examples/js/postprocessing/RenderPass.js"></script>


  <!-- ShaderPass.js库，一个ShaderPass调用一个自定义着色器代码就构成一个后处理通道 -->
  <script src="http://www.yanhuangxueyuan.com/threejs/examples/js/postprocessing/ShaderPass.js"></script>

  <!-- 引入CopyShader.js库  CopyShader.js包含着色器代码，着色器代码功能：采样一张图片像素赋值给片元 -->
  <script src="http://www.yanhuangxueyuan.com/threejs/examples/js/shaders/CopyShader.js"></script>

</head>

<body>

  <!-- 顶点着色器，通用下面格式 -->
  <script id="vertexShader" type="x-shader/x-vertex">
    // 声明一个变量vUv表示uv坐标插值后的结果
    varying vec2 vUv;
    void main(){
      // 纹理坐标插值计算
      vUv = uv;
      // projectionMatrix投影矩阵  modelViewMatrix模型视图矩阵
      gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );
    }
  </script>
  <!-- 片元着色器  提取R分量-->
  <script id="fragmentShader" type="x-shader/x-fragment">
    // 默认设置颜色贴图的变量是tDiffuse
    uniform sampler2D tDiffuse;
    varying vec2 vUv;
    void main() {
      //采集纹素
      vec4 tColor = texture2D( tDiffuse, vUv );
      //逐片元赋值，RGB相同均为亮度值，用黑白两色表达图片的明暗变化
      gl_FragColor = vec4(tColor.r,0,0,1);
    }
  </script>
  <script>
    /**
     * 创建场景对象
     */
    var scene = new THREE.Scene();
    /**
     * 创建网格模型
     */
    var geometry = new THREE.SphereGeometry(60, 30, 30); //创建一个立方体几何对象
    var material = new THREE.MeshBasicMaterial({
      map: new THREE.TextureLoader().load('Earth.png')
    }); //材质对象
    var mesh = new THREE.Mesh(geometry, material); //网格模型对象
    scene.add(mesh); //网格模型添加到场景中
    /**
     * 相机设置
     */
    var width = window.innerWidth; //窗口宽度
    var height = window.innerHeight; //窗口高度
    var k = width / height; //窗口宽高比
    var s = 100; //三维场景缩放系数
    //创建相机对象
    var camera = new THREE.OrthographicCamera(-s * k, s * k, s, -s, 1, 1000);
    camera.position.set(20, 20, 300); //设置相机位置
    camera.lookAt(scene.position); //设置相机方向(指向的场景对象)

    /**
     * 创建渲染器对象
     */
    var renderer = new THREE.WebGLRenderer({
      antialias: true
    });
    renderer.setSize(width, height);
    // renderer.setClearColor(0xb9d3ff, 1); //设置背景颜色
    document.body.appendChild(renderer.domElement); //body元素中插入canvas对象

    //自定义后处理通道
    var GreyShader = {
      uniforms: {
        // 和着色器tDiffuse变量对应
        // THREE.ShaderPass会把渲染结果，也就是一张图片的像素值对应Texture对象赋值给tDiffuse
        tDiffuse: {
          value: null
        },
      },
      vertexShader: document.getElementById('vertexShader').textContent,
      fragmentShader: document.getElementById('fragmentShader').textContent,
    }
    // GreyShader作为THREE.ShaderPass的参数
    var grayShaderPass = new THREE.ShaderPass(GreyShader);
    // 设置renderToScreen为true，表示经过该通道处理后显示在Canvas画布上
    // 默认false，会把渲染结果存储到WebGL渲染目标对象WebGLRenderTarget，像素数据不会显示在canvas画布上
    grayShaderPass.renderToScreen = true;

    // 创建一个渲染器通道，场景和相机作为参数
    var renderPass = new THREE.RenderPass(scene, camera);

    // 把渲染器作为参数
    var composer = new THREE.EffectComposer(renderer);
    // 设置renderPass通道，该通道并不对渲染结果的像素数据进行处理
    composer.addPass(renderPass);
    // 设置灰度图通道grayShaderPass，对渲染结果进行灰度计算处理
    composer.addPass(grayShaderPass);


    // 渲染函数
    function render() {
       // 使用后处理模块EffectComposer，可通过该对象的render方法调用渲染器的render方法
      composer.render();
      requestAnimationFrame(render);
    }
    render();
    var controls = new THREE.OrbitControls(camera,renderer.domElement); //创建控件对象
  </script>
</body>

</html>
